﻿using Coldairarrow.Entity;
using Coldairarrow.Entity.BTB_StaffUsers;
using Coldairarrow.Entity.Frontstage.Valickets;
using Coldairarrow.Entity.Goods;
using Coldairarrow.Entity.Order;
using Coldairarrow.IBusiness;
using Coldairarrow.IBusiness.Order;
using Coldairarrow.Util;
using EFCore.Sharding;
using LinqKit;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Coldairarrow.Business.Order
{
    public class BTB_RefundMasterBusiness : BaseBusiness<BTB_RefundMaster>, IBTB_RefundMasterBusiness, ITransientDependency
    {
        readonly IOperator _operator;
        readonly IOrder_DecimalBusiness _order;
        readonly IBTB_RefundDetailsBusiness _bTB_RefundDetailsBusiness;
        public BTB_RefundMasterBusiness(IDbAccessor db, IOperator @operator, IOrder_DecimalBusiness order, IBTB_RefundDetailsBusiness bTB_RefundDetailsBusiness)
            : base(db)
        {
            _operator = @operator;
            _order = order;
            _bTB_RefundDetailsBusiness = bTB_RefundDetailsBusiness;
        }


        public async Task AddDataAsync(SetRefundOderDTO model)
        {
            int? SumNum = 0;
            decimal? SumPrice = 0;

            var OrderMast = Db.GetIQueryable<Order_Master>().Where(q => q.Id == model.OrderId && q.CreatorId.Equals(_operator.UserId) && q.PayState > 0).ToList();
            if (OrderMast.Count > 0)
            {
                var mList = GetIQueryable().Where(x => x.OrderId.Equals(model.OrderId)).ToList();
                if (mList.Count == 0)
                {
                    var Id = GuidHelper.GenerateKey();
                    SumPrice = OrderMast[0].TotalPrice;

                    //查询所有商品
                    var gList = Db.GetIQueryable<Order_Decimal>().Where(q => q.OrderMaster_Id == OrderMast[0].Id).ToList();

                    List<BTB_RefundDetails> sList = new List<BTB_RefundDetails>();
                    foreach (var item in gList)
                    {
                        SumNum += item.Products_Num;
                      
                        foreach (var items in gList)
                        {
                            BTB_RefundDetails bTB_RefundDetails = new BTB_RefundDetails()
                            {
                                Id = GuidHelper.GenerateKey(),
                                MasterId = Id,
                                OrderId = items.OrderMaster_Id,
                                ProductsId = items.Products_Id,
                                Price = items.ProductPrice,
                                Num = items.Products_Num,
                                PayState = OrderMast[0].PayState,
                                CreatorId = _operator.UserId,
                                CreateTime = DateTime.Now,
                                EditorId = _operator.UserId,
                                State = 0,
                                Order_DecimalId = item.Id,
                                EditTime = DateTime.Now
                            };
                            sList.Add(bTB_RefundDetails);
                        }

                        
                    }

                    BTB_RefundMaster bTB_RefundMaster = new BTB_RefundMaster()
                    {
                        Id = Id,
                        VailTicketId = OrderMast[0].VailTicketId,
                        RTypeId = model.RTypeId,
                        Resion = model.Resion,
                        Note = model.Note,
                        ImgURL = model.ImgURL,
                        SumPrice = SumPrice,
                        SumNum = SumNum,
                        PayState = OrderMast[0].PayState,
                        CreatorId = _operator.UserId,
                        OrderId = OrderMast[0].Id,
                        CreateTime = DateTime.Now,
                        EditorId = _operator.UserId,
                        EditTime = DateTime.Now
                    };

                    await InsertAsync(bTB_RefundMaster);
                    await Db.InsertAsync(sList);

                    OrderMast[0].RefundState = OrderMast[0].OrderState;
                    OrderMast[0].OrderState = 7;
                    await Db.UpdateAsync(OrderMast[0]);

                }
                else
                {
                    throw new BusException("此订单已申请退款，无法重复提交！");
                }

            }
            else
            {
                throw new BusException("此订单查询失败，退款失败！");
            }

        }

        public async Task<PageResult<BTB_RefundDTO>> GetGoodsList(PageInput<BTB_RefundDTO> input)
        {
            var bTB_RefundDTO = input.Search;

            var result = Db.GetIQueryable<BTB_RefundDetails>();
            //订单id
            if (!string.IsNullOrEmpty(bTB_RefundDTO.OrderId))
            {
                result = result.Where(k => k.OrderId == bTB_RefundDTO.OrderId);
            }
            if (!bTB_RefundDTO.State.IsNullOrEmpty())
            {
                result = result.Where(p => p.State.Equals(bTB_RefundDTO.State));
            }
            if (bTB_RefundDTO.StartTime.HasValue && bTB_RefundDTO.EndTime.HasValue)
            {
                result = result.Where(k => k.CreateTime >= bTB_RefundDTO.StartTime && k.CreateTime <= bTB_RefundDTO.EndTime);
            }
            var where = LinqHelper.True<BTB_RefundDetails>();

            int count = result.Count();
            var q = await result.Select(s => new BTB_RefundDTO
            {
                Id = s.Id,
                CreatorId = s.CreatorId,
                OrderId = s.OrderId,
                SumNum = s.Num,
                SumPrice = s.Price,
                State = s.State,
                EditorId = s.EditorId,
                EditTime = s.EditTime,
                ProductNames = Db.GetIQueryable<Order_Decimal>(true).Where(z => z.Id == s.Order_DecimalId).FirstOrDefault().ProductNames,
                ProductitemNames = Db.GetIQueryable<Order_Decimal>(true).Where(z => z.Id == s.Order_DecimalId).FirstOrDefault().ProductitemNames,
                CreateTime = s.CreateTime,
                bTB_RefundDetails = Db.GetIQueryable<BTB_RefundDetails>(true).Where(z => z.Id == s.Id)
            }).Skip((input.PageIndex - 1) * input.PageRows)
                .Take(input.PageRows)
                .ToListAsync();

            return new PageResult<BTB_RefundDTO> { Data = q, Total = count };
        }

        /// <summary>
        /// 获取退款申请列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageResult<GetRefundOderDTO>> GetOrdersListAsnyc(PageInput<SearchDTO> input)
        {
            Expression<Func<BTB_RefundMaster, Order_Master, BTB_StaffUser, BS_UserVailTicket, GetRefundOderDTO>> select = (a, b, c, d) => new GetRefundOderDTO
            {
                BeforeRefundState = b.RefundState,
                UserName = c.NickName,
                Phone = c.phone,
                OrderCode = b.OrderCode,
                YSMoney = b.YSMoney,
                SSMoney = b.TotalPrice,
                YHMoney = d.Ticket_Amount,
                GoodsNum= b.Totalnum
            };
            var search = input.Search;
            select = select.BuildExtendSelectExpre();

            var dList = from a in GetIQueryable().AsExpandable()
                        join b in Db.GetIQueryable<Order_Master>() on a.OrderId equals b.Id into ab
                        from b in ab.DefaultIfEmpty()
                        join c in Db.GetIQueryable<BTB_StaffUser>() on b.CreatorId equals c.id into bc
                        from c in bc.DefaultIfEmpty()
                        join d in Db.GetIQueryable<BS_UserVailTicket>() on b.VailTicketId equals d.Id into bd
                        from d in bd.DefaultIfEmpty()
                        select @select.Invoke(a, b, c, d);

            if (search.State.HasValue)
            {
                dList = dList.Where(X => X.State == search.State);
            }

            if(!search.Search.IsNullOrEmpty())
            {
                dList = dList.Where(X => X.UserName.Contains(search.Search)|| X.OrderCode.Contains(search.Search) || X.Phone.Contains(search.Search) || X.Resion.Contains(search.Search));
            }

            var datas = await dList.GetPageResultAsync(input);

            return datas;
        }

        /// <summary>
        /// 获取退款订单详情
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<RefundOrderDto> GetTheDataAsnyc(IdInputDTO input)
        {

            var model = await GetEntityAsync(input.id);

            var res = Db.GetIQueryable<Order_Master>().Where(p => p.Id.Equals(model.OrderId));

            int count = res.Count();
            if (count > 0)
            {
                var result = await res.OrderBy(p => p.CreateTime).Select(p =>
                 new RefundOrderDto
                 {
                     Id = p.Id,
                     CreatTime = p.CreateTime,
                     OrderCode = p.OrderCode,
                     state = p.OrderState,
                     TatolPrice = p.TotalPrice,
                     AddressId = p.Address_Id,
                     payState = p.PayState,
                     IsDiscuss = p.IsDiscuss,
                     YSMoney = p.YSMoney,
                     IsPointOrder = p.IsPointOrder,
                     TotalPoint = p.TotalPoint,
                     InvoiceData = p.InvoiceData,
                     InvoiceState = p.InvoiceState,
                     payeinfoAddress = p.payeinfoAddress,
                     payeinfoPhone = p.payeinfoPhone,
                     payeinfoName = p.payeinfoName,
                     //Invoice = Db.GetIQueryable<Invoice_Info>(false).SingleOrDefault(r => r.Id.Equals(p.Invoice_InfoId)),
                     //AddressDto = Db.GetIQueryable<BTB_ShippingAddress>(true).SingleOrDefault(r => r.id.Equals(p.Address_Id)),
                     UserInfo = Db.GetIQueryable<BTB_StaffUser>(true).Where(r => r.id.Equals(p.CreatorId)).Select(x =>  new BTB_StaffUser { 
                         id = x.id,
                         NickName = x.NickName,
                         phone = x.phone,
                         CreateTime =x.CreateTime,
                         EditTime = x.EditTime,
                         Sex = x.Sex
                     }).SingleOrDefault(),
                     TicketDTO = Db.GetIQueryable<BS_UserVailTicket>(true).SingleOrDefault(r => r.Id.Equals(p.VailTicketId)),
                     RefundDto = Db.GetIQueryable<BTB_RefundMaster>(false).FirstOrDefault(r => r.OrderId.Equals(p.Id)),
                     orderProducts = Db.GetIQueryable<Order_Decimal>(false).Where(s => s.OrderCode.Equals(p.OrderCode) && s.OrderMaster_Id.Equals(p.Id))
                               .Select(s => new OrderProduct
                               {
                                   Id = s.Id,
                                   Price = s.ProductPrice,
                                   productId = s.Product_Id,
                                   Image = s.ProductImage,
                                   itemName = s.ProductitemNames,
                                   Name = s.ProductNames,
                                   DATA0 = s.DATA0,
                                   Num = (int)s.Products_Num

                               })
                 }).ToListAsync();

                return result.FirstOrDefault();
            }
            else
            {
                throw new BusException("查询订单信息失败，查询退款信息失败");
            }



        }
    }
}